package Model;
import java.awt.Color;
import java.io.IOException;

import java.util.List;

import org.apache.pdfbox.exceptions.COSVisitorException;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.edit.PDPageContentStream;
import org.apache.pdfbox.pdmodel.font.PDFont;
import org.apache.pdfbox.pdmodel.font.PDType1Font;



public class PDFmanager {
	
	
	String path = "";

	public String getPath() {
		return path;
	}

	public void setPath(String path) {
		this.path = path;
	}

	public PDFmanager() {

	}

	/**
	 * Metodo pubblico che crea il PDF con il titolo, l'artista ed il testo
	 * inserito dall'utente
	 * 
	 * @param title
	 *            Stringa contenente il titolo del brano
	 * @param artist
	 *            Stringa contenente l'artista del brano
	 * @param text
	 *            Vettore di stringhe contenente le righe del testo
	 */
	private void createPDFSong(String title, String artist, String[] text, String path) {

		String fileName = artist + "_" + title;

		PDDocument doc = CreateDocument();

		writeSongPDF(doc, title, artist, text);

		closeDocument(doc, fileName, path+"/");

	}
	
	public void createPDFIndex(List<Song> canzoni,String path, String fileName) {

		
		PDDocument doc = CreateDocument();

		writeSongIndex(doc, canzoni);

		closeDocument(doc, fileName, path+"/");

	}
	
	
	
	

	private void writeSongIndex(PDDocument doc, List<Song> canzoni) {
		PDPage page = new PDPage();
		doc.addPage(page);

		try {
			PDPageContentStream content = new PDPageContentStream(doc, page);

			// scrivo i testi
			content.beginText();
			setTitle(content, "Indice");
			//setArtist(content, artist);
			setIndex(content, canzoni);
			content.endText();

			// Disegno la tabella
			//drawTable(content);

			content.close();
		} catch (Exception io) {
			System.out.println(io);
		}
		
	}

	private void setIndex(PDPageContentStream content, List<Song> canzoni) {
		PDFont font = PDType1Font.HELVETICA;

		int rowsForColumn = 58;

		// System.out.println(body.length);

		try {
			content.moveTextPositionByAmount(-40, -70);
			content.setFont(font, 10);
			content.setNonStrokingColor(Color.BLACK);
			int pagina = 3;
			int lineMaxsize = 50;
			// se ci sto in una colonna sola scrivo solo la prima colonna
			if (canzoni.size() <= rowsForColumn) {
				for (Song song : canzoni) {
					
				String riga = song.getSinger() + " - "+ song.getTitle();
				int puntini = lineMaxsize - riga.length();
				//System.out.println(puntini);
				
				 for (int i=0; i<puntini; i++){
					 riga=riga+"-";
				 }
				riga = riga+pagina;
				pagina++;
					content.drawString(riga);
					content.moveTextPositionByAmount(0, -10);
				}
				
			}

			// se ho bisogno di 2 colonne scrivo prima e seconda colonna
			else if (canzoni.size() <= (rowsForColumn * 2)) {

				// scrivo la prima colonna

				for (Song song : canzoni) {
					
					String riga = song.getSinger() + " - "+ song.getTitle();
					int puntini = lineMaxsize - riga.length();
					//System.out.println(puntini);
					
					 for (int i=0; i<puntini; i++){
						 riga=riga+"-";
					 }
					riga = riga+pagina;
					pagina++;
						content.drawString(riga);
						content.moveTextPositionByAmount(0, -10);
					}

				// scrivo la seconda colonna
				content.moveTextPositionByAmount(260, 580);

				for (Song song : canzoni) {
					
					String riga = song.getSinger() + " - "+ song.getTitle();
					int puntini = lineMaxsize - riga.length();
					//System.out.println(puntini);
					
					 for (int i=0; i<puntini; i++){
						 riga=riga+"-";
					 }
					riga = riga+pagina;
					pagina++;
						content.drawString(riga);
						content.moveTextPositionByAmount(0, -10);
					}
				
			}

			// se ho troppo testo creo la nuova pagina
			else {
				// TODO
				System.out.println("Else");
			}

		} catch (IOException e) {
			e.printStackTrace();
		}

		
	}

	/**
	 * Metodo che salva il PDF e chiude il documento PDF
	 * 
	 * @param doc
	 *            Documento PDF su cui scrivere
	 * @param fileName
	 *            Stringa contenente il nome da dare al file
	 */

	private void closeDocument(PDDocument doc, String fileName, String filePath) {
		try {
			doc.save(filePath+fileName + ".pdf");
			doc.close();
		} catch (COSVisitorException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	/**
	 * Metodo che crea la nuova pagina PDF, scrive titolo, artista e testo. poi
	 * disegna la tabella che contiene il testo
	 * 
	 * @param doc
	 *            Documento PDF su cui scrivere
	 * @param title
	 *            Stringa contenente il titolo del brano
	 * @param artist
	 *            Stringa contenente l'artista del brano
	 * @param text
	 *            Vettore di stringhe contenente le righe del testo
	 */
	private void writeSongPDF(PDDocument doc, String title, String artist,
			String[] text) {

		PDPage page = new PDPage();
		doc.addPage(page);

		try {
			PDPageContentStream content = new PDPageContentStream(doc, page);

			// scrivo i testi
			content.beginText();
			setTitle(content, title);
			setArtist(content, artist);
			setBody(content, text);
			content.endText();

			// Disegno la tabella
			drawTable(content);

			content.close();
		} catch (Exception io) {
			System.out.println(io);
		}

	}
	
	

	/**
	 * Metodo che crea il nuovo documento PDF
	 * 
	 * @return il nuovo documento PDF
	 */
	
	private PDDocument CreateDocument() {
		// creazione del documento PDF
		PDDocument doc = null;
		try {
			doc = new PDDocument();
		} catch (IOException ie) {
			System.out.println(ie);
		}

		return doc;

	}

	/**
	 * Metodo che imposta la stringa del titolo all'interno della pagina PDF
	 * 
	 * @param content
	 *            lo stream dati su cui scrivere
	 * @param title
	 *            la stringa del titolo
	 */
	public void setTitle(PDPageContentStream content, String title) {

		PDFont font = PDType1Font.HELVETICA_BOLD_OBLIQUE;

		try {

			content.setFont(font, 18);
			content.setNonStrokingColor(Color.RED);
			content.moveTextPositionByAmount(80, 730);
			content.drawString(title.toUpperCase());

		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	/**
	 * Metodo che imposta la stringa dell'artista all'interno della pagina PDF
	 * 
	 * @param content
	 *            lo stream dati su cui scrivere
	 * @param Artist
	 *            la stringa dell'artista
	 */
	public void setArtist(PDPageContentStream content, String Artist) {

		PDFont font = PDType1Font.HELVETICA_BOLD;

		try {

			content.setFont(font, 14);
			content.setNonStrokingColor(Color.BLACK);
			content.moveTextPositionByAmount(20, -20);
			content.drawString(Artist);

		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	/**
	 * Metodo che imposta la stringa del testo all'interno della pagina PDF
	 * 
	 * @param content
	 *            lo stream dati su cui scrivere
	 * @param body
	 *            l'array che costituiscono le righe del testo
	 */
	public void setBody(PDPageContentStream content, String[] body) {

		PDFont font = PDType1Font.HELVETICA;

		int rowsForColumn = 58;

		// System.out.println(body.length);

		try {
			content.moveTextPositionByAmount(-40, -70);
			content.setFont(font, 10);
			content.setNonStrokingColor(Color.BLACK);

			// se ci sto in una colonna sola scrivo solo la prima colonna
			if (body.length <= rowsForColumn) {
				for (int i = 0; i < body.length; i++) {
					checkColor(content, i);
					content.drawString(body[i]);
					content.moveTextPositionByAmount(0, -10);
				}
				// System.out.println("Primo if");
			}

			// se ho bisogno di 2 colonne scrivo prima e seconda colonna
			else if (body.length <= (rowsForColumn * 2)) {

				// scrivo la prima colonna

				for (int i = 0; i < rowsForColumn; i++) {
					checkColor(content, i);
					content.drawString(body[i]);
					content.moveTextPositionByAmount(0, -10);
				}

				// scrivo la seconda colonna
				content.moveTextPositionByAmount(260, 580);

				for (int i = rowsForColumn; i < body.length; i++) {
					checkColor(content, i);
					content.drawString(body[i]);
					content.moveTextPositionByAmount(0, -10);
				}
				// System.out.println("Secondo if");
			}

			// se ho troppo testo creo la nuova pagina
			else {
				// TODO
				System.out.println("Else");
			}

		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	/**
	 * Metodo che setta il carattere BOLD se la riga contiene accordi, non BOLD
	 * se si tratta del testo
	 * 
	 * @param content
	 *            lo stream dati su cui scrivere
	 * @param i
	 *            riga che sto scrivendo
	 */

	private void checkColor(PDPageContentStream content, int i) {

		try {
			if (i % 2 == 0)
				content.setFont(PDType1Font.HELVETICA_BOLD, 10);
			else
				content.setFont(PDType1Font.HELVETICA, 10);
		} catch (IOException e) {
			e.printStackTrace();
		}

	}

	/**
	 * metodo che disegna le linee che costituiscono la tabella
	 * 
	 * @param contentStream
	 *            lo stream dati su cui disegnare
	 * @throws IOException
	 */

	public void drawTable(PDPageContentStream contentStream) throws IOException {
		final int topSX_x = 45;
		final int topSX_y = 660;
		final int bottomDX_x = 570;
		final int bottomDX_y = 50;
		final int Ctr_x = 50 + ((bottomDX_x - topSX_x) / 2);

		// riga orizzontale alta
		contentStream.drawLine(topSX_x, topSX_y, bottomDX_x, topSX_y);
		// riga orizzontale bassa
		contentStream.drawLine(topSX_x, bottomDX_y, bottomDX_x, bottomDX_y);
		// riga verticale SX
		contentStream.drawLine(topSX_x, topSX_y, topSX_x, bottomDX_y);
		// riga verticale DX
		contentStream.drawLine(bottomDX_x, topSX_y, bottomDX_x, bottomDX_y);
		// riga verticale CTR
		contentStream.drawLine(Ctr_x, topSX_y, Ctr_x, bottomDX_y);

	}

	public void createPDFSong(Song song, String pDFSavepath) {
		path = pDFSavepath;
		createPDFSong(song.getTitle(),song.getSinger(),song.getText(), path);
	}

	
}
